﻿using System;
using AzureDiagMon.Common.Helpers;
using AzureDiagMon.Common.Properties;

namespace AzureDiagMon.Common.Dtos
{
    public class DateFilter : ICloneable
    {
        public enum DateFilterKind
        {
            Interval,
            TimeSpanFromNow
        }

        public string DisplayName { get; private set; }
        public TimeSpan? TimeSpanFromNow { get; private set; }
        public delegate void HandleCalculateStartAndEndTime(out DateTime startDate, out DateTime endDate, out bool isNowEnded);
        private HandleCalculateStartAndEndTime CalculateStartAndEndMethod { get; set; }
        public DateFilterKind Kind { get; set; }
        public DateTime? CustomStartDate { get; set; }
        public DateTime? CustomEndDate { get; set; }
        public bool IsNowEnded { get; private set; }
        public bool IsCustom { get; private set; }

        public DateFilter(string displayName)
        {
            DisplayName = displayName;
            IsCustom = true;
        }

        public DateFilter(string displayName, TimeSpan? timeSpanFromNow)
        {
            DisplayName = displayName;
            TimeSpanFromNow = timeSpanFromNow;
            IsNowEnded = true;
        }

        public DateFilter(string displayName, HandleCalculateStartAndEndTime calculateStartAndEnd)
        {
            DisplayName = displayName;
            CalculateStartAndEndMethod = calculateStartAndEnd;
        }

        public bool CalculateStartAndEndDate(out DateTime startDate, out DateTime endDate, out bool isNowEnded)
        {
            if (CalculateStartAndEndMethod != null)
            {
                CalculateStartAndEndMethod.Invoke(out startDate, out endDate, out isNowEnded);
                return true;
            }
            if (TimeSpanFromNow.HasValue)
            {
                endDate = DateTime.Now;
                startDate = endDate.Subtract(TimeSpanFromNow.Value);
                isNowEnded = true;
                return true;
            }

            startDate = CustomStartDate.HasValue ? CustomStartDate.Value : new DateTime(2000, 1, 1);
            endDate = CustomEndDate.HasValue ? CustomEndDate.Value : DateTime.Now;
            isNowEnded = !CustomEndDate.HasValue;
            return true;
        }

        public readonly static DateFilter[] DefaultFilters =
            new[]
                {
                    new DateFilter(Resources.DateFilter_DefaultFilters_Last_hour, new TimeSpan(0,1,0,0)), 
                    new DateFilter(Resources.DateFilter_DefaultFilters_Last_3_hours, new TimeSpan(0,3,0,0)), 
                    new DateFilter(Resources.DateFilter_DefaultFilters_Today, delegate(out DateTime startDate, out DateTime endDate, out bool isNowEnded)
                                                         {
                                                                 startDate = DateTime.Today;
                                                                 endDate = DateTime.Now;
                                                                 isNowEnded = true;
                                                         }), 
                    new DateFilter(Resources.DateFilter_DefaultFilters_Last_24_hours, new TimeSpan(1,0,0,0)), 
                    new DateFilter(Resources.DateFilter_DefaultFilters_Last_48_hours, new TimeSpan(2,0,0,0)), 
                    new DateFilter(Resources.DateFilter_DefaultFilters_This_week, delegate(out DateTime startDate, out DateTime endDate, out bool isNowEnded)
                                                             {
                                                                 startDate = DateTime.Now.StartOfWeek();
                                                                 endDate = DateTime.Now;
                                                                 isNowEnded = true;
                                                             }), 
                    new DateFilter(Resources.DateFilter_DefaultFilters_This_month, delegate(out DateTime startDate, out DateTime endDate, out bool isNowEnded)
                                                              {
                                                                      startDate = DateTime.Now.StartOfMonth();
                                                                      endDate = DateTime.Now;
                                                                     isNowEnded = true;
                                                              }), 
                    new DateFilter(Resources.DateFilter_DefaultFilters_This_year, delegate(out DateTime startDate, out DateTime endDate, out bool isNowEnded)
                                                             {
                                                                     startDate = DateTime.Now.StartOfYear();
                                                                     endDate = DateTime.Now;
                                                                     isNowEnded = true;
                                                             }), 
                    new DateFilter(Resources.DateFilter_DefaultFilters_Custom), 
                };

        public override string ToString()
        {
            return DisplayName;
        }

        public object Clone()
        {
            return MemberwiseClone();
        }
    }
}
